package com.starbucks.opencase.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.starbucks.opencase.config.configOC;
import com.starbucks.opencase.enums.enumCMKey;
import com.starbucks.opencase.enums.enumCMTip;
import com.starbucks.opencase.enums.enumTip;
import com.starbucks.opencase.function.funCommand;
import com.starbucks.opencase.function.funTest;
import com.starbucks.opencase.request.reqAdminCommand;
import com.starbucks.opencase.request.reqAdminUpdatePlayerProperties;
import com.starbucks.opencase.request.reqAdminUpdateScanProperties;
import com.starbucks.opencase.request.reqData;
import com.starbucks.opencase.response.resAdminPropertiesQueryInfo;
import com.starbucks.opencase.response.resStatus;
import com.starbucks.opencase.tool.toolAdminAccount;
import com.starbucks.opencase.tool.toolProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;

@RestController
@RequestMapping("/admin/properties")
public class conAdminProperties {
    @Autowired
    private funCommand funCommand;
    @Autowired
    private funTest funTest;
    @Autowired
    private toolAdminAccount toolAdminAccount;
    @Autowired
    private toolProperties toolProperties;
    @Autowired
    private configOC configOC;
    @PostMapping("/query/info")
    public resAdminPropertiesQueryInfo queryInfo(@RequestBody reqAdminCommand info) {
        resAdminPropertiesQueryInfo res=new resAdminPropertiesQueryInfo();
        if(info.getPhone()==null || info.getPhone().isEmpty()){
            res.setTip(enumTip.no_has_phone.getTip());
            return res;
        }
        if(info.getCommand().isEmpty()){
            res.setTip(enumTip.no_has_command.getTip());
            return res;
        }
        String[] com= funCommand.decode(info.getCommand());
        if(com==null){
            res.setTip(enumTip.error_command_decode.getTip());
            return res;
        }
        if(!info.getPhone().equals(com[0])){
            res.setTip(enumTip.error_command.getTip());
            return res;
        }
        if(res.getTimestamp()>Long.parseLong(com[1])){
            res.setTip(enumTip.past_que_command.getTip());
            return res;
        }
        res.setData(toolProperties.queryInfo());
        res.setStatus(true);
        res.setTip(enumTip.success_query.getTip());
        return res;
    }

    @PostMapping("/update/player")
    public resStatus updatePlayer(@RequestBody reqAdminUpdatePlayerProperties info) {
        resStatus res = new resStatus();
        if (info.getPhone().isEmpty()) {
            res.setTip(enumTip.no_has_phone.getTip());
            return res;
        }
        if (info.getCommand().isEmpty()) {
            res.setTip(enumTip.no_has_command.getTip());
            return res;
        }
        String[] com = funCommand.decode(info.getCommand());
        if (com == null) {
            res.setTip(enumTip.error_command.getTip());
            return res;
        }
        if (!info.getPhone().equals(com[0])) {
            res.setTip(enumTip.error_command.getTip());
            return res;
        }
        if (res.getTimestamp() > Long.parseLong(com[1])) {
            res.setTip(enumTip.past_que_command.getTip());
            return res;
        }
        if (info.getNuNickname() == null || info.getNuNickname().isEmpty()) {
            res.setTip(enumTip.no_has_nickname.getTip());
            return res;
        }
        if (info.getNuPet() == null || info.getNuPet().isEmpty()) {
            res.setTip(enumTip.no_has_pet.getTip());
            return res;
        }
        res.setStatus(toolProperties.updatePlayer(info.getNuNickname(), info.getNuEnergy(), info.getNuPet()));
        res.setTip(res.isStatus() ? enumTip.success_update.getTip() : enumTip.failed_update.getTip());
        return res;
    }

    @PostMapping("/update/scan")
    public resStatus updateScan(@RequestBody reqAdminUpdateScanProperties info) {
        resStatus res = new resStatus();
        if (info.getPhone().isEmpty()) {
            res.setTip(enumTip.no_has_phone.getTip());
            return res;
        }
        if (info.getCommand().isEmpty()) {
            res.setTip(enumTip.no_has_command.getTip());
            return res;
        }
        String[] com = funCommand.decode(info.getCommand());
        if (com == null) {
            res.setTip(enumTip.error_command.getTip());
            return res;
        }
        if (!info.getPhone().equals(com[0])) {
            res.setTip(enumTip.error_command.getTip());
            return res;
        }
        if (res.getTimestamp() > Long.parseLong(com[1])) {
            res.setTip(enumTip.past_que_command.getTip());
            return res;
        }
        res.setStatus(toolProperties.updateScan(info.getExpendEnergy(), info.getProEnergy(), info.getProGoods(), info.getProPet(),
                info.getProBusinessman(), info.getProPlayer(), info.getProEnergyAward()));
        res.setTip(res.isStatus() ? enumTip.success_update.getTip() : enumTip.failed_update.getTip());
        return res;
    }
    @PostMapping("/update/loading")
    public String updateLoadingImg(@RequestBody reqData info){
        try{
            ObjectMapper om = new ObjectMapper();
            JsonNode me = om.readTree(info.getData());
            ObjectNode on=om.createObjectNode();
            on.put(enumCMKey.timestamp.name(),System.currentTimeMillis());
            on.put(enumCMKey.status.name(), false);
            if(!funTest.hasPhone(me,on))return on.toString();
            if(!funTest.hasCommand(me,on))return on.toString();
            String phone= funTest.getPhone(me);
            String command= funTest.getCommand(me);
            if(!toolAdminAccount.queryCommand(phone).equals(command)){
                on.put(enumCMKey.tip.name(), enumCMTip.error_command.getTip());
                return on.toString();
            }
            if(!funTest.hasData(me,on))return on.toString();
            String data= funTest.getData(me);
            ByteArrayInputStream in=new ByteArrayInputStream(Base64.getDecoder().decode(data));
            BufferedImage bi=ImageIO.read(in);
            in.close();
            ImageIO.write(bi,"png",new File("data/other/loading.png"));
            on.put(enumCMKey.status.name(), true);
            return on.toString();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
    @PostMapping("/update/background/bgm")
    public String updateBackgroundBgm(@RequestBody reqData info){
        try{
            ObjectMapper om = new ObjectMapper();
            JsonNode me = om.readTree(info.getData());
            ObjectNode on=om.createObjectNode();
            on.put(enumCMKey.timestamp.name(),System.currentTimeMillis());
            on.put(enumCMKey.status.name(), false);
            if(!funTest.hasPhone(me,on))return on.toString();
            if(!funTest.hasCommand(me,on))return on.toString();
            String phone= funTest.getPhone(me);
            String command= funTest.getCommand(me);
            if(!toolAdminAccount.queryCommand(phone).equals(command)){
                on.put(enumCMKey.tip.name(), enumCMTip.error_command.getTip());
                return on.toString();
            }
            if(!funTest.hasData(me,on))return on.toString();
            String data= funTest.getData(me);
            File f=new File("data/other");
            if(!f.exists())f.mkdirs();
            f=new File("data/other/bgm.mp3");
            if(!f.exists())f.createNewFile();
            OutputStream out=new FileOutputStream(f);
            out.write(Base64.getDecoder().decode(data));
            out.flush();
            out.close();
            on.put(enumCMKey.status.name(), true);
            return on.toString();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}
